/**
 * @file
 * @description
 * @author 黄敏
 * @since 2025-09-12 08:58
 */
import type { Page } from 'playwright'

import { waitStep } from './wait'

// 工具函数：等待标签关闭完成（基于轮询同步获取，避免跨导航 evaluate 被销毁）
export async function closeTabsAndWaitForCloseEvent(win: Page, ids: number[]) {
  // 记录变更前的 ID 列表
  const beforeIds = (await win.evaluate(() =>
    _pre_.browser.getTopTabs().map(t => t.id)
  )) as number[]

  // 触发关闭（同步返回，避免长时间挂在 evaluate 内）
  await win.evaluate(ids => {
    _pre_.browser.closeTabs(ids)
  }, ids)

  // 等待：这些 id 都不再出现在当前 tabs 列表中
  await win.waitForFunction(ids => {
    const current = new Set(_pre_.browser.getTopTabs().map(t => t.id))
    return (ids as number[]).every(id => !current.has(id))
  }, ids)

  // 计算已关闭的 id（以实际结果为准）
  const afterIds = (await win.evaluate(() => _pre_.browser.getTopTabs().map(t => t.id))) as number[]
  return beforeIds.filter(id => !afterIds.includes(id))
}

// 工具函数：创建标签页并等待 UI/数据就绪（不依赖事件监听，避免 evaluate 跨导航被销毁）
export async function addTabAndWait(win: Page, urlOrTabs?: F2.tab.CreateInput) {
  // 记录变更前数量与 ID
  const before = (await win.evaluate(() => _pre_.browser.getTopTabs())) as F2.tab.Entity[]
  const beforeCount = before.length
  const beforeIds = before.map(t => t.id)

  // 触发创建
  await win.evaluate(param => {
    _pre_.browser.addTab(param)
  }, urlOrTabs)

  // 期望新增数量（保守估计：字符串=1，数组=length，其它=0）
  const expectedAdd = Array.isArray(urlOrTabs)
    ? urlOrTabs.length
    : typeof urlOrTabs === 'string'
      ? 1
      : 0

  // 等待：数量达到预期的增加；若 expectedAdd 为 0，则等待至少出现一个新 ID
  await win.waitForFunction(
    ({ expected, baseline, beforeIds }) => {
      const list = _pre_.browser.getTopTabs()
      const ids = list.map(t => t.id)
      const newCount = ids.filter(id => !(beforeIds as number[]).includes(id)).length

      return expected > 0
        ? list.length >= (baseline as number) + (expected as number)
        : newCount >= 1
    },
    { expected: expectedAdd, baseline: beforeCount, beforeIds }
  )

  // 读取最新 tabs，返回新创建的条目（以 ID 差集判断）
  const after = (await win.evaluate(() => _pre_.browser.getTopTabs())) as F2.tab.Entity[]
  const created = after.filter(t => !beforeIds.includes(t.id))
  return created as F2.tab.Entity[]
}

// 工具函数：关闭所有标签页（用于测试用例初始化）
export async function closeAllTabs(win: Page) {
  // 获取所有标签页的 ID
  const allTabIds = (await win.evaluate(() => {
    return _pre_.browser.getTopTabs().map(t => t.id)
  })) as number[]

  // 如果有标签页，则关闭它们
  if (allTabIds.length > 0) {
    await closeTabsAndWaitForCloseEvent(win, allTabIds)
    await waitStep(win, '清理：关闭所有标签页')
  }
}
